package controller

import (
	"fmt"
	"net/http"
	"projorg/model"
	"projorg/service"
	"strconv"

	"github.com/gin-gonic/gin"
)

// IndexHandler ...
func IndexHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"msg":  "success",
		"code": 200,
		"data": "index",
	})
}

// TodoHTTPAddHandler ...
type TodoHTTPAddHandler struct {
	Title string `json:"title"`
}

// AddTodoHandler ...
func AddTodoHandler(c *gin.Context) {
	var newTodo TodoHTTPAddHandler
	if err := c.Bind(&newTodo); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":  "bind error",
			"code": 5002,
			"data": "",
		})
	} else {
		todo := &model.Todo{
			Title:  newTodo.Title,
			Status: 0,
		}
		if err := service.AddTodoService(todo); err != nil {
			c.JSON(http.StatusOK, gin.H{
				"msg":  "add item error",
				"code": 5004,
				"data": "",
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"msg":  "success",
				"code": 200,
				"data": todo,
			})
		}
	}
}

// GetTodoHandler ...
func GetTodoHandler(c *gin.Context) {
	var (
		todo *model.Todo
		err  error
	)

	id := c.Param("id")
	idInt, _ := strconv.Atoi(id)

	todo, err = service.GetTodoService(idInt)
	fmt.Println(todo)
	if err != nil {
		fmt.Println("接口获取详细失败 ", err)
		c.JSON(http.StatusOK, gin.H{
			"msg":  "获取详情失败",
			"code": 5001,
			"data": "",
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":  "success",
			"code": 200,
			"data": todo,
		})
	}
}

// TodoHTTPUpdateHandler ...
type TodoHTTPUpdateHandler struct {
	Title  string `json:"title"`
	Status uint   `json:"status"`
}

// UpdateTodoHandler ...
func UpdateTodoHandler(c *gin.Context) {
	id := c.Param("id")
	idInt, _ := strconv.Atoi(id)
	idUint64, _ := strconv.ParseUint(id, 10, 64)
	idUint := uint(idUint64)
	var updateTodo TodoHTTPUpdateHandler
	if err := c.Bind(&updateTodo); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":  "bind error",
			"code": 5005,
			"data": "",
		})
	} else {
		_, err = service.GetTodoService(idInt)
		// 更新的如果不存在
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"msg":  "待更新记录不存在",
				"code": 5007,
				"data": "",
			})
		} else {
			todo := &model.Todo{
				Title:  updateTodo.Title,
				Status: updateTodo.Status,
			}
			// 如果 todo.ID = idUint 放到这里则SQL为
			// UPDATE `gocrud_todo` SET `status` = 0, `title` = '这是第3个测试的todo item，你搞错啦4', `updated_at` = '2020-12-23 16:15:59'  WHERE `gocrud_todo`.`deleted_at` IS NULL AND `gocrud_todo`.`id` = 3 AND ((id = 3))
			// 多了一个 AND `gocrud_todo`.`id` = 3
			if err := service.UpdateTodoService(todo, idUint); err != nil {
				c.JSON(http.StatusOK, gin.H{
					"msg":  "update item error",
					"code": 5006,
					"data": "",
				})
			} else {
				// 注意：这里todo.ID 位置不同，实际对应的数据库执行的SQL语句不同
				// 这里对应的SQL是
				// UPDATE `gocrud_todo` SET `status` = 1, `title` = '这是第3个测试的todo item，你搞错啦5', `updated_at` = '2020-12-23 16:17:21'  WHERE `gocrud_todo`.`deleted_at` IS NULL AND ((id = 3))
				todo.ID = idUint
				c.JSON(http.StatusOK, gin.H{
					"msg":  "success",
					"code": 200,
					"data": todo,
				})
			}
		}

	}

}

// DeleteTodoHandler ...
func DeleteTodoHandler(c *gin.Context) {
	id := c.Param("id")
	idInt, _ := strconv.Atoi(id)
	// gorm 默认的删除方式不是真正的删除，是 deleted_at 为空的时候更新 deleted_at 字段，所以更新是”成功“ 的
	// 所以需要提前判断 待删除的记录是否存在，不存在则直接返回报错
	_, err := service.GetTodoService(idInt)
	// 更新的如果不存在
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"msg":  "待删除记录不存在",
			"code": 5007,
			"data": "",
		})
	} else {
		if err := service.DeleteTodoService(idInt); err != nil {
			c.JSON(http.StatusOK, gin.H{
				"msg":  "删除失败",
				"code": 5006,
				"data": "",
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"msg":  "删除成功",
				"code": 200,
				"data": "",
			})
		}
	}

}

// ListTodoHandler ...
func ListTodoHandler(c *gin.Context) {
	var (
		todos []*model.Todo
		err   error
	)

	todos, err = service.ListTodoService()
	if err != nil {
		fmt.Println("接口获取列表失败 ", err)
		c.JSON(http.StatusOK, gin.H{
			"msg":  "获取列表失败",
			"code": 5002,
			"data": "",
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"msg":  "success",
			"code": 200,
			"data": &todos,
		})
	}
}
